using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using CKY.AgentPlatform.Conversations;

namespace CKY.AgentPlatform.Services
{
    /// <summary>
    * 对话管理器 - 负责Agent会话的生命周期管理
    /// </summary>
    public class ConversationManager : ApplicationService, IConversationManager
    {
        private readonly IRepository<Conversation, Guid> _conversationRepository;
        private readonly ILogger<ConversationManager> _logger;

        public ConversationManager(
            IRepository<Conversation, Guid> conversationRepository,
            ILogger<ConversationManager> logger)
        {
            _conversationRepository = conversationRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取或创建会话
        /// </summary>
        /// <param name="conversationId">会话ID</param>
        /// <param name="agentId">Agent ID</param>
        /// <param name="userId">用户ID</param>
        /// <returns>会话实体</returns>
        public async Task<Conversation> GetOrCreateConversationAsync(Guid conversationId, Guid agentId, Guid userId)
        {
            try
            {
                // 尝试获取现有会话
                var existingConversation = await _conversationRepository.FirstOrDefaultAsync(c => c.Id == conversationId);
                if (existingConversation != null)
                {
                    // 验证会话权限
                    if (existingConversation.AgentId != agentId || existingConversation.UserId != userId)
                    {
                        throw new UnauthorizedAccessException($"无权访问会话: {conversationId}");
                    }

                    // 更新会话活动时间
                    existingConversation.UpdateActivity();
                    await _conversationRepository.UpdateAsync(existingConversation);

                    return existingConversation;
                }

                // 创建新会话
                var newConversation = new Conversation(
                    conversationId,
                    agentId,
                    userId,
                    $"New Conversation {DateTime.UtcNow:yyyyMMdd-HHmmss}");

                await _conversationRepository.InsertAsync(newConversation);

                _logger.LogInformation("创建新会话: {ConversationId}, Agent: {AgentId}, User: {UserId}",
                    conversationId, agentId, userId);

                return newConversation;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取或创建会话失败: {ConversationId}", conversationId);
                throw;
            }
        }

        /// <summary>
        /// 获取会话历史记录
        /// </summary>
        /// <param name="conversationId">会话ID</param>
        /// <param name="maxMessages">最大消息数量</param>
        /// <returns>会话消息列表</returns>
        public async Task<List<ConversationMessage>> GetConversationHistoryAsync(Guid conversationId, int maxMessages = 50)
        {
            try
            {
                var conversation = await _conversationRepository.GetAsync(conversationId);

                // 获取消息历史（按时间排序，限制数量）
                var messages = conversation.Messages
                    .OrderBy(m => m.Timestamp)
                    .TakeLast(maxMessages)
                    .ToList();

                return messages;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取会话历史失败: {ConversationId}", conversationId);
                throw;
            }
        }

        /// <summary>
        /// 添加消息到会话
        /// </summary>
        /// <param name="conversationId">会话ID</param>
        /// <param name="message">消息内容</param>
        public async Task AddMessageAsync(Guid conversationId, ConversationMessage message)
        {
            try
            {
                var conversation = await _conversationRepository.GetAsync(conversationId);

                // 添加消息
                conversation.AddMessage(message);

                // 更新会话统计信息
                conversation.UpdateMessageStats();
                conversation.UpdateActivity();

                await _conversationRepository.UpdateAsync(conversation);

                _logger.LogDebug("添加消息到会话: {ConversationId}, 角色: {Role}, 长度: {Length}",
                    conversationId, message.Role, message.Content?.Length ?? 0);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "添加消息失败: {ConversationId}", conversationId);
                throw;
            }
        }

        /// <summary>
        /// 更新会话活动时间
        /// </summary>
        /// <param name="conversationId">会话ID</param>
        public async Task UpdateConversationActivityAsync(Guid conversationId)
        {
            try
            {
                var conversation = await _conversationRepository.GetAsync(conversationId);
                conversation.UpdateActivity();
                await _conversationRepository.UpdateAsync(conversation);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新会话活动时间失败: {ConversationId}", conversationId);
                throw;
            }
        }

        /// <summary>
        * 获取用户的会话列表
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="agentId">可选的Agent ID</param>
        /// <param name="maxResults">最大结果数量</param>
        /// <returns>会话列表</returns>
        public async Task<List<Conversation>> GetUserConversationsAsync(Guid userId, Guid? agentId = null, int maxResults = 100)
        {
            try
            {
                var query = await _conversationRepository.GetQueryableAsync();

                // 过滤条件
                query = query.Where(c => c.UserId == userId);
                if (agentId.HasValue)
                {
                    query = query.Where(c => c.AgentId == agentId.Value);
                }

                // 按最后活动时间排序，限制结果数量
                var conversations = await AsyncExecuter.ToListAsync(
                    query.OrderByDescending(c => c.LastActivityTime)
                        .Take(maxResults)
                );

                return conversations;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取用户会话列表失败: {UserId}, AgentId: {AgentId}", userId, agentId);
                throw;
            }
        }

        /// <summary>
        /// 获取Agent的会话列表
        /// </summary>
        /// <param name="agentId">Agent ID</param>
        /// <param name="maxResults">最大结果数量</param>
        /// <returns>会话列表</returns>
        public async Task<List<Conversation>> GetAgentConversationsAsync(Guid agentId, int maxResults = 100)
        {
            try
            {
                var query = await _conversationRepository.GetQueryableAsync();

                var conversations = await AsyncExecuter.ToListAsync(
                    query.Where(c => c.AgentId == agentId)
                        .OrderByDescending(c => c.LastActivityTime)
                        .Take(maxResults)
                );

                return conversations;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取Agent会话列表失败: {AgentId}", agentId);
                throw;
            }
        }

        /// <summary>
        /// 删除会话
        /// </summary>
        /// <param name="conversationId">会话ID</param>
        /// <param name="userId">用户ID（用于权限验证）</param>
        public async Task DeleteConversationAsync(Guid conversationId, Guid userId)
        {
            try
            {
                var conversation = await _conversationRepository.GetAsync(conversationId);

                // 验证权限
                if (conversation.UserId != userId)
                {
                    throw new UnauthorizedAccessException($"无权删除会话: {conversationId}");
                }

                await _conversationRepository.DeleteAsync(conversationId);

                _logger.LogInformation("删除会话: {ConversationId}", conversationId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除会话失败: {ConversationId}", conversationId);
                throw;
            }
        }

        /// <summary>
        /// 清理过期会话
        /// </summary>
        /// <param name="olderThanDays">早于多少天的会话</param>
        /// <returns>删除的会话数量</returns>
        public async Task<int> CleanupExpiredConversationsAsync(int olderThanDays = 30)
        {
            try
            {
                var cutoffDate = DateTime.UtcNow.AddDays(-olderThanDays);
                var query = await _conversationRepository.GetQueryableAsync();

                var expiredConversations = await AsyncExecuter.ToListAsync(
                    query.Where(c => c.LastActivityTime < cutoffDate)
                );

                foreach (var conversation in expiredConversations)
                {
                    await _conversationRepository.DeleteAsync(conversation.Id);
                }

                _logger.LogInformation("清理过期会话完成: {Count} 个会话被删除", expiredConversations.Count);
                return expiredConversations.Count;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理过期会话失败");
                return 0;
            }
        }

        /// <summary>
        /// 获取会话统计信息
        /// </summary>
        /// <param name="conversationId">会话ID</param>
        /// <returns>统计信息</returns>
        public async Task<ConversationStats> GetConversationStatsAsync(Guid conversationId)
        {
            try
            {
                var conversation = await _conversationRepository.GetAsync(conversationId);

                return new ConversationStats
                {
                    ConversationId = conversationId,
                    Title = conversation.Title,
                    MessageCount = conversation.MessageCount,
                    TotalTokensUsed = conversation.TotalTokensUsed,
                    CreatedAt = conversation.CreationTime,
                    LastActivityTime = conversation.LastActivityTime,
                    Duration = conversation.LastActivityTime - conversation.CreationTime,
                    AverageTokensPerMessage = conversation.MessageCount > 0 ?
                        (double)conversation.TotalTokensUsed / conversation.MessageCount : 0
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取会话统计失败: {ConversationId}", conversationId);
                throw;
            }
        }

        /// <summary>
        /// 搜索会话内容
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="searchTerm">搜索词</param>
        /// <param name="maxResults">最大结果数量</param>
        /// <returns>匹配的会话列表</returns>
        public async Task<List<Conversation>> SearchConversationsAsync(Guid userId, string searchTerm, int maxResults = 20)
        {
            try
            {
                var query = await _conversationRepository.GetQueryableAsync();

                // 简单的内存搜索（在生产环境中应该使用全文搜索）
                var allConversations = await AsyncExecuter.ToListAsync(
                    query.Where(c => c.UserId == userId)
                        .OrderByDescending(c => c.LastActivityTime)
                        .Take(100) // 限制搜索范围
                );

                var filteredConversations = allConversations
                    .Where(c => c.Messages.Any(m =>
                        m.Content?.Contains(searchTerm, StringComparison.OrdinalIgnoreCase) ?? false))
                    .Take(maxResults)
                    .ToList();

                return filteredConversations;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "搜索会话失败: {UserId}, 搜索词: {SearchTerm}", userId, searchTerm);
                throw;
            }
        }

        /// <summary>
        /// 导出会话记录
        /// </summary>
        /// <param name="conversationId">会话ID</param>
        /// <param name="format">导出格式</param>
        /// <returns>导出的内容</returns>
        public async Task<string> ExportConversationAsync(Guid conversationId, ConversationExportFormat format)
        {
            try
            {
                var conversation = await _conversationRepository.GetAsync(conversationId);

                return format switch
                {
                    ConversationExportFormat.Json => await ExportToJsonAsync(conversation),
                    ConversationExportFormat.Text => await ExportToTextAsync(conversation),
                    ConversationExportFormat.Markdown => await ExportToMarkdownAsync(conversation),
                    _ => throw new NotSupportedException($"不支持的导出格式: {format}")
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出会话失败: {ConversationId}, 格式: {Format}", conversationId, format);
                throw;
            }
        }

        /// <summary>
        /// 导出为JSON格式
        /// </summary>
        private async Task<string> ExportToJsonAsync(Conversation conversation)
        {
            await Task.Yield(); // 模拟异步操作

            var exportData = new
            {
                conversation.Id,
                conversation.Title,
                conversation.AgentId,
                conversation.UserId,
                conversation.MessageCount,
                conversation.TotalTokensUsed,
                CreatedAt = conversation.CreationTime,
                LastActivityTime = conversation.LastActivityTime,
                Messages = conversation.Messages.Select(m => new
                {
                    m.Role,
                    m.Content,
                    m.Timestamp,
                    m.TokensUsed,
                    ToolCalls = m.ToolCalls?.Select(tc => new
                    {
                        tc.ToolName,
                        tc.Success,
                        tc.ErrorMessage
                    })
                })
            };

            return JsonSerializer.Serialize(exportData, new JsonSerializerOptions
            {
                WriteIndented = true,
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            });
        }

        /// <summary>
        /// 导出为文本格式
        /// </summary>
        private async Task<string> ExportToTextAsync(Conversation conversation)
        {
            await Task.Yield(); // 模拟异步操作

            var result = $"Conversation: {conversation.Title}\n";
            result += $"Agent ID: {conversation.AgentId}\n";
            result += $"User ID: {conversation.UserId}\n";
            result += $"Created: {conversation.CreationTime:yyyy-MM-dd HH:mm:ss}\n";
            result += $"Last Activity: {conversation.LastActivityTime:yyyy-MM-dd HH:mm:ss}\n";
            result += $"Messages: {conversation.MessageCount}\n";
            result += $"Total Tokens: {conversation.TotalTokensUsed}\n";
            result += new string('-', 50) + "\n\n";

            foreach (var message in conversation.Messages.OrderBy(m => m.Timestamp))
            {
                result += $"[{message.Timestamp:yyyy-MM-dd HH:mm:ss}] {message.Role.ToUpper()}:\n";
                result += $"{message.Content}\n";

                if (message.ToolCalls?.Any() ?? false)
                {
                    result += "Tool Calls:\n";
                    foreach (var toolCall in message.ToolCalls)
                    {
                        result += $"  - {toolCall.ToolName}: {(toolCall.Success ? "Success" : "Failed")}\n";
                        if (!string.IsNullOrWhiteSpace(toolCall.ErrorMessage))
                        {
                            result += $"    Error: {toolCall.ErrorMessage}\n";
                        }
                    }
                }

                result += "\n";
            }

            return result;
        }

        /// <summary>
        /// 导出为Markdown格式
        /// </summary>
        private async Task<string> ExportToMarkdownAsync(Conversation conversation)
        {
            await Task.Yield(); // 模拟异步操作

            var result = $"# {conversation.Title}\n\n";
            result += $"**Agent ID:** {conversation.AgentId}\n\n";
            result += $"**User ID:** {conversation.UserId}\n\n";
            result += $"**Created:** {conversation.CreationTime:yyyy-MM-dd HH:mm:ss}\n\n";
            result += $"**Last Activity:** {conversation.LastActivityTime:yyyy-MM-dd HH:mm:ss}\n\n";
            result += $"**Messages:** {conversation.MessageCount}\n\n";
            result += $"**Total Tokens:** {conversation.TotalTokensUsed}\n\n";
            result += "---\n\n";

            foreach (var message in conversation.Messages.OrderBy(m => m.Timestamp))
            {
                result += $"## {message.Role.ToUpper()} ({message.Timestamp:yyyy-MM-dd HH:mm:ss})\n\n";
                result += $"{message.Content}\n\n";

                if (message.ToolCalls?.Any() ?? false)
                {
                    result += "### Tool Calls\n\n";
                    foreach (var toolCall in message.ToolCalls)
                    {
                        var status = toolCall.Success ? "✅" : "❌";
                        result += $"- {status} **{toolCall.ToolName}**\n";
                        if (!string.IsNullOrWhiteSpace(toolCall.ErrorMessage))
                        {
                            result += $"  - Error: {toolCall.ErrorMessage}\n";
                        }
                    }
                    result += "\n";
                }

                result += "---\n\n";
            }

            return result;
        }
    }

    /// <summary>
    /// 对话统计信息
    /// </summary>
    public class ConversationStats
    {
        public Guid ConversationId { get; set; }
        public string Title { get; set; }
        public int MessageCount { get; set; }
        public long TotalTokensUsed { get; set; }
        public DateTime CreatedAt { get; set; }
        public DateTime LastActivityTime { get; set; }
        public TimeSpan Duration { get; set; }
        public double AverageTokensPerMessage { get; set; }
    }

    /// <summary>
    /// 会话导出格式
    /// </summary>
    public enum ConversationExportFormat
    {
        Json,
        Text,
        Markdown
    }
}